package com.jhws.business.car.service;

import com.jhws.util.LogHelper;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.BoundListOperations;
import org.springframework.data.redis.core.RedisConnectionUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.TimeUnit;

@SuppressWarnings("unchecked")
@Service
public class RedisQueueService {
    @Resource
    private RedisTemplate serializeTemplate;

    //从尾部弹出数据
    public <T> T takeFromTail(int timeout, String... keys) throws InterruptedException {
        RedisConnectionFactory factory = serializeTemplate.getConnectionFactory();
        RedisConnection connection = RedisConnectionUtils.getConnection(factory);
        T t = null;
        try {
            byte[] bytes[] = new byte[keys.length][];
            for (int i = 0; i < keys.length; i++) {
                bytes[i] = serializeTemplate.getKeySerializer().serialize(keys[i]);
            }
            List<byte[]> results = connection.bRPop(timeout, bytes);
            if (!CollectionUtils.isEmpty(results)) {
                t = (T) serializeTemplate.getValueSerializer().deserialize(results.get(1));
            }
        } finally {
            RedisConnectionUtils.releaseConnection(connection, factory);
        }
        return t;
    }

    //从头部开始弹出数据
    public <T> T takeFromHead(int timeout, String... keys) throws InterruptedException {
        RedisConnectionFactory factory = serializeTemplate.getConnectionFactory();
        RedisConnection connection = RedisConnectionUtils.getConnection(factory);
        T t = null;
        try {
            byte[] bytes[] = new byte[keys.length][];
            for (int i = 0; i < keys.length; i++) {
                bytes[i] = serializeTemplate.getKeySerializer().serialize(keys[i]);
            }
            List<byte[]> results = connection.bLPop(timeout, bytes);
            if (!CollectionUtils.isEmpty(results)) {
                t = (T) serializeTemplate.getValueSerializer().deserialize(results.get(1));
            }
        } finally {
            RedisConnectionUtils.releaseConnection(connection, factory);
        }
        return t;
    }

    //从队列的头插入
    public <T> Long pushFromHead(String key, T value) {
        return getOperations(key).leftPush(value);
    }

    //从队列的头插入, 带超时时间
    public <T> void pushFromHeadTimeout(String key, T value, int seconds) {
        BoundListOperations<String, T> operations = getOperations(key);
        operations.leftPush(value);
        if (seconds > 0) {
            LogHelper.e("timeout: " + seconds);
            operations.expire(seconds, TimeUnit.SECONDS);
        }
    }

    //从队列尾部插入
    public <T> void pushFromTail(String key, T value) {
        getOperations(key).rightPush(value);
    }

    //从队列尾部插入，带超时时间
    public <T> void pushFromTailTimeout(String key, T value, int seconds) {
        BoundListOperations<String, T> operations = getOperations(key);
        operations.rightPush(value);
        if (seconds > 0) {
            LogHelper.e("timeout: " + seconds);
            operations.expire(seconds, TimeUnit.SECONDS);
        }
    }

    //从左边开始删除
    public <T> T removeFromHead(String key) {
        return (T) getOperations(key).leftPop();
    }

    //从右边开始删除
    public <T> T removeFromTail(String key) {
        return (T) getOperations(key).rightPop();
    }

    //key获取operations
    private <T> BoundListOperations<String, T> getOperations(String key) {
        return serializeTemplate.boundListOps(key);
    }
}
